package com.google.appengine.codelab;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.Entity;

@SuppressWarnings("serial")
public class FraudesFaixaValorServlet extends BaseServlet 
{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		
		EstabelecimentosSuspeitosServlet.cargaTeste();
		
		request.setAttribute("paises", Localidade.listarPaises());
		request.setAttribute("bandeiras", Midia.listarBandeiras());
		request.setAttribute("tipos", Fraude.listarTiposFraudes());
		request.setAttribute("tiposTransacao", Transacao.listarTiposTransacao());
		
		RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/jsp/frmFraudesFaixaValor.jsp");  
		rd.forward(request, response); 
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try
		{
			String dataIncialFraude = request.getParameter("dataInicial");
			String dataFinalFraude = request.getParameter("dataFinal");
			String dataInicialTransacao = request.getParameter("dataInicialTransacao");
			String dataFinalTransacao = request.getParameter("dataFinalTransacao");
			String pais = request.getParameter("pais");
			String estado = request.getParameter("estado");
			String cidade = request.getParameter("cidade");
			String tipo = request.getParameter("tipo");
			String bandeira = request.getParameter("bandeira");
			String tipoTransacao = request.getParameter("tipoTransacao");
			String[] valorInicial = request.getParameterValues("valorIncial");
			String[] valorFinal = request.getParameterValues("valorFinal");
	
			validarFaixas(valorInicial,valorFinal);
			
			request.setAttribute("datainicial", dataIncialFraude);
			request.setAttribute("dataFinal", dataFinalFraude);
			request.setAttribute("dataInicialTransacao", dataInicialTransacao);
			request.setAttribute("dataFinalTransacao", dataFinalTransacao);		
			request.setAttribute("pais", pais);
			request.setAttribute("estado", estado);
			request.setAttribute("cidade", cidade);
			request.setAttribute("tipo", tipo);
			request.setAttribute("tipoTransacao", tipoTransacao);
			request.setAttribute("bandeira", bandeira);		
			
			request.setAttribute("usuario", "Administrador");
			request.setAttribute("dataAtual", new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()));
		
			StringBuilder intervalos = new StringBuilder();
	
			List<Entity> faixaFraudesTotal = UserStory12Servlet.getFraudesByParameters(tipo, dataIncialFraude, dataFinalFraude, 
					dataInicialTransacao, dataFinalTransacao, tipoTransacao, bandeira, pais, estado, cidade, "0","-1");
			BigDecimal total = new BigDecimal(faixaFraudesTotal.size());
			
			if( faixaFraudesTotal.size() <= 0 ){
				throw new RuntimeException("Nenhuma fraude encontrada para a pesquisa.");
			}			
	
			BigDecimal somadorPorcentagem = BigDecimal.ZERO;
			
			for( int i=0; i < valorInicial.length ; i++ ){
				
				Double valor1 = getValor(valorInicial[i]);
				Double valor2 = getValor(valorFinal[i]);
				
				if( valor1.compareTo(valor2) != 0 ){
					List<Entity> faixaFraudes = UserStory12Servlet.getFraudesByParameters(tipo, dataIncialFraude, dataFinalFraude, 
						dataInicialTransacao, dataFinalTransacao, tipoTransacao, bandeira, pais, estado, cidade, valor1.toString(),valor2.toString());
	
					BigDecimal porcentagem = new BigDecimal(faixaFraudes.size()).multiply(new BigDecimal(100)).divide(total,2, RoundingMode.HALF_EVEN);
					somadorPorcentagem = somadorPorcentagem.add(porcentagem);
					
					intervalos.append("['R$ "+ valor1.toString() +" - R$ "+ valor2.toString() +"', "+ porcentagem +"],");
				}
			}
			
			if( somadorPorcentagem.compareTo(new BigDecimal(100)) < 0  ){
				intervalos.append("['Outras Faixas',");
				intervalos.append(new BigDecimal(100).subtract(somadorPorcentagem));
				intervalos.append("],");
			}
			
			request.setAttribute("intervalos", intervalos.toString());
			
			request.getRequestDispatcher("/WEB-INF/jsp/relatorioFraudesFaixaValor.jsp").forward(request, response);
		}
		catch( Exception e ){
			e.printStackTrace();
			request.setAttribute("erro", e.getMessage());
			request.getRequestDispatcher("/WEB-INF/jsp/frmFraudesFaixaValor.jsp").forward(request, response);
		}
	}

	private void validarFaixas(String[] valorInicial, String[] valorFinal) 
	{
		for( int count1=0; count1 < valorInicial.length ; count1++ )
		{
			Double valor1 = getValor(valorInicial[count1]);
			Double valor2 = getValor(valorFinal[count1]);
			
			if( valor1 > valor2 ){
				throw new RuntimeException("Faixa de valores inválida.");
			}

			if( valor1.compareTo(valor2) == 0 && valor1 > 0d){
				throw new RuntimeException("Faixa de valores inválida.");
			}

			if( valor1.compareTo(0d) == 0 && valor2.compareTo(0d) == 0 ){
				continue;
			}
			
			for( int count2=0; count2 < valorInicial.length ; count2++ )
			{
				Double valorTmp1 = getValor(valorInicial[count2]);
				Double valorTmp2 = getValor(valorFinal[count2]);
				
				if( valorTmp1.compareTo(0d) == 0 && valorTmp2.compareTo(0d) == 0 ){
					continue;
				}
				
				if( count2 != count1 && (valor1.compareTo(valorTmp2)==0) || (valor2.compareTo(valorTmp1)==0) || (valorTmp1<valor2 && valorTmp1 > valor1) || (valorTmp2>valor1 && valorTmp2 < valor2) ){
					throw new RuntimeException("Faixa de valores coincidente.");
				}				
			}
		}
	}
	
	private Double getValor( String valor ){
		if( valor == null || valor.isEmpty() ){
			return 0.0;
		}
		return Double.parseDouble(valor.replaceAll("\\.", "").replaceAll(",", "."));  
		
	}
	
}
